#include "Mock.h"
#include<cstring>

using namespace std;


Mock::Mock(){
	stat = StatTable::getInstance();
	var = VarTable::getInstance();
	proc = ProcTable::getInstance();
	modstat = ModifyStatTable::getInstance();
	usestat = UsesStatTable::getInstance();
	modvar = ModifyVarTable::getInstance();
	usevar = UsesVarTable::getInstance();
	modproc = ModifyProcTable::getInstance();
	useproc = UsesProcTable::getInstance();
	call = CallsTable::getInstance();
}

//--Function to handle Select entity query---
int Mock::getAll(list<string>&s, int type){
	char str[50];
	int x;

	if(type==_VARIABLE){
		x = var->getTotalSize();
		for(int i=0;i<x;i++){
			if(var->getVarType(i) == NUMERIC_EXPR_TYPE_VARIABLE)
			s.push_back(var->getVarName(i));
		}
	}
	else if(type==_PROCEDURE){
		x = proc->getSize();
		for(int i=0;i<x;i++)
			s.push_back(proc->getProcName(i));
	}
	else if(type==_CONSTANT){
		x = var->getTotalSize();
		for(int i=0;i<x;i++)
			if(var->getVarType(i)==NUMERIC_EXPR_TYPE_CONSTANT)
				s.push_back(var->getVarName(i));
	}
	else{
		x =  stat->getNoofStat();
		for(int i=1;i<=x;i++){
			if((stat->getType(i) == type)||type==_STMT){
			sprintf(str,"%d",i);
			s.push_back(str);
			}
		}
	}
	return 1;
}
//------------------Main Function to process Follows query------------------------
int Mock::getFollow(vector<int>& result1, vector<int>& result2, Argument arg1, Argument arg2){
	if(arg1.argumentType==INTARGUMENT){
		getFollowing(result1, result2, arg1.argument, arg2.argument,arg1.argumentType);
		if(result2.size()==0)
			return -1;
	}
	else if(arg2.argumentType==INTARGUMENT){
		getFollowedby(result1, result2,arg1.argument,arg2.argument,arg2.argumentType);
		if(result1.size()==0)
			return -1;
	}
	else{
		getFollowing(result1, result2, arg1.argument, arg2.argument,arg1.argumentType);
		if(result1.size()==0||result2.size()==0)
			return -1;
		//getFollowedby(result.resultVector[arg1.argument].resultEntity[arg1.argumentInd],arg1.argument,arg2.argument,arg2.argumentType);
	}
	/*if(arg2.argumentType!=INTARGUMENT){
	if(result.selectedType == arg2.argument){
	getFollowing(result.resultVector[arg2.argument].resultEntity[arg2.argumentInd], arg1.argument, arg2.argument,arg1.argumentType);
	}
	else if(result.selectedType == arg1.argument)
	getFollowedby(result.resultVector[arg1.argument].resultEntity[arg1.argumentInd],arg1.argument,arg2.argument,arg2.argumentType);
	}
	else
	getFollowedby(result.resultVector[arg1.argument].resultEntity[arg1.argumentInd],arg1.argument,arg2.argument,arg2.argumentType);*/
	return 1;
}

//------------------Main Function to process Follows* query------------------------
int Mock::getFollowT(vector<int>& result1, vector<int>& result2, Argument arg1, Argument arg2){
	if(arg1.argumentType==INTARGUMENT){
		getFollowingT(result1, result2, arg1.argument, arg2.argument,arg1.argumentType);
		if(result2.size()==0)
			return -1;
	}
	else if(arg2.argumentType==INTARGUMENT){
		getFollowedbyT(result1, result2,arg1.argument,arg2.argument,arg2.argumentType);
		if(result1.size()==0)
			return -1;
	}
	else{
		getFollowingT(result1, result2, arg1.argument, arg2.argument,arg1.argumentType);
		if(result1.size()==0||result2.size()==0)
			return -1;
		//getFollowedby(result.resultVector[arg1.argument].resultEntity[arg1.argumentInd],arg1.argument,arg2.argument,arg2.argumentType);
	}
	return 1;
}

//------------------Main Function to process Parent query------------------------
int Mock::getParent(vector<int>& result1,vector<int>& result2, Argument arg1, Argument arg2){
	if(arg2.argumentType==INTARGUMENT){
		getPar(result1,result2, arg1.argument, arg2.argument,arg2.argumentType);
		if(result1.size()==0)
			return -1;
	}
	else if(arg1.argumentType==INTARGUMENT){
		getChild(result1,result2,arg1.argument,arg2.argument,arg1.argumentType);
		if(result2.size()==0)
			return -1;
	}
	else{
		//getPar(result1, result2,arg1.argument, arg2.argument,arg2.argumentType);
		getChild(result1,result2,arg1.argument,arg2.argument,arg1.argumentType);
		if(result1.size()==0||result2.size()==0)
			return -1;
	}
	/*if(arg1.argumentType!=INTARGUMENT){
	if(result.selectedType == arg1.argument){
	getPar(result.resultVector[arg1.argument].resultEntity[arg1.argumentInd], arg1.argument, arg2.argument,arg2.argumentType);
	}
	else if(result.selectedType == arg2.argument)
	getChild(result.resultVector[arg2.argument].resultEntity[arg2.argumentInd],arg1.argument,arg2.argument,arg1.argumentType);
	}
	else
	getChild(result.resultVector[arg2.argument].resultEntity[arg2.argumentInd],arg2.argument,arg2.argument,arg1.argumentType);*/

	return 1;
}

//------------------Main Function to process Parent* query------------------------
int Mock::getParentT(vector<int>& result1,vector<int>& result2, Argument arg1, Argument arg2){
	if(arg2.argumentType==INTARGUMENT){
		getParT(result1,result2, arg1.argument, arg2.argument,arg2.argumentType);
		if(result1.size()==0)
			return -1;
	}
	else if(arg1.argumentType==INTARGUMENT){
		getChildT(result1,result2,arg1.argument,arg2.argument,arg1.argumentType);
		if(result2.size()==0)
			return -1;
	}
	else{
		//getParT(result1, result2,arg1.argument, arg2.argument,arg2.argumentType);
		getChildT(result1,result2,arg1.argument,arg2.argument,arg1.argumentType);
		if(result1.size()==0||result2.size()==0)
			return -1;
	}
	return 1;
}

int Mock::getNext(vector<int>& result1, vector<int>& result2, Argument arg1, Argument arg2){
	if(arg1.argumentType==INTARGUMENT){
		getNextafter(result1, result2, arg1.argument, arg2.argument,arg1.argumentType);
		if(result2.size()==0)
			return -1;
	}
	else if(arg2.argumentType==INTARGUMENT){
		getNextbefore(result1, result2,arg1.argument,arg2.argument,arg2.argumentType);
		if(result1.size()==0)
			return -1;
	}
	else{
		getNextafter(result1, result2, arg1.argument, arg2.argument,arg1.argumentType);
		if(result1.size()==0||result2.size()==0)
			return -1;
		//getFollowedby(result.resultVector[arg1.argument].resultEntity[arg1.argumentInd],arg1.argument,arg2.argument,arg2.argumentType);
	}
	return 1;
}

int Mock::getNextT(vector<int>& result1, vector<int>& result2, Argument arg1, Argument arg2){
	if(arg1.argumentType==INTARGUMENT){
		getNextafterT(result1, result2, arg1.argument, arg2.argument,arg1.argumentType);
		if(result2.size()==0)
			return -1;
	}
	else if(arg2.argumentType==INTARGUMENT){
		getNextbeforeT(result1, result2,arg1.argument,arg2.argument,arg2.argumentType);
		if(result1.size()==0)
			return -1;
	}
	else{
		getNextafterT(result1, result2, arg1.argument, arg2.argument,arg1.argumentType);
		if(result1.size()==0||result2.size()==0)
			return -1;
		//getFollowedby(result.resultVector[arg1.argument].resultEntity[arg1.argumentInd],arg1.argument,arg2.argument,arg2.argumentType);
	}
	return 1;
}

//------------------Main Function to process Modifies query------------------------
int Mock::getModify(vector<int>& result1, vector<int>& result2, Argument arg1, Argument arg2) 
{
	int resultExists=0;
	
	/*if(arg1.argumentType==result.selectedType && arg1.argumentInd!=result.resultIndex)
		result.resultType==RESULT_BOOLEAN;

	else if(arg2.argumentType==result.selectedType && arg2.argumentInd!=result.resultIndex)
		result.resultType==RESULT_BOOLEAN;*/

	if(arg1.argumentType==ARGUMENT && arg2.argumentType==VARARGUMENT)
		resultExists=getModifies(result1, result2,arg1,arg2);
	
	else if(arg1.argumentType!=ARGUMENT && arg2.argumentType==ARGUMENT)
		resultExists=getModifiedBy(result1, result2, arg1,arg2);

	else if(arg1.argumentType==ARGUMENT && arg2.argumentType==ARGUMENT)
		resultExists=getModifies(result1, result2,arg1,arg2);

	else if((arg1.argumentType==INTARGUMENT || arg1.argumentType==PROCARGUMENT) && arg2.argumentType==VARARGUMENT)
		resultExists=getModifies(result1, result2,arg1,arg2);

	/*if(result.resultType==RESULT_BOOLEAN)
	{
		if(result.resultVector.size()>0)
			result.resultExists = true;
		else
			result.resultExists = false;
	}*/
			
	return resultExists;
}
//------------------Main Function to process Uses query------------------------
int Mock::getUses(vector<int>& result1, vector<int>& result2, Argument arg1, Argument arg2)
{
	int resultExists;

	/*if(arg1.argumentType==result.selectedType && arg1.argumentInd!=result.resultIndex)
		result.resultType==RESULT_BOOLEAN;

	else if(arg2.argumentType==result.selectedType && arg2.argumentInd!=result.resultIndex)
		result.resultType==RESULT_BOOLEAN;*/

	if(arg1.argumentType==ARGUMENT && arg2.argumentType==VARARGUMENT)
		resultExists=getUsess(result1, result2,arg1,arg2);
	
	else if(arg1.argumentType!=ARGUMENT && arg2.argumentType==ARGUMENT)
		resultExists=getUsedBy(result1, result2, arg1,arg2);

	else if(arg1.argumentType==ARGUMENT && arg2.argumentType==ARGUMENT)
		resultExists=getUsess(result1, result2,arg1,arg2);

	else if((arg1.argumentType==INTARGUMENT || arg1.argumentType==PROCARGUMENT) && arg2.argumentType==VARARGUMENT)
		resultExists=getModifies(result1, result2,arg1,arg2);

	/*if(result.resultType==RESULT_BOOLEAN)
	{
		if(result.resultVector.size()>0)
			result.resultExists = true;
		else
			result.resultExists = false;
	}
	*/
	return -1;
}

//------------------Main Function to process Calls query------------------------

int Mock::getCalls(vector<int>& result1, vector<int>& result2, Argument arg1, Argument arg2)
{
	vector<PROC_INDEX> temp;
	/* Select p ... Calls(p,"q")*/
	if(arg1.argumentType==ARGUMENT && arg2.argumentType==PROCARGUMENT)
	{
		for(int i=0;i<proc->getSize();i++)
		{
			if(call->isCalled(i,arg2.argument))
				result1.push_back(i);
		}

		return 2;
	}

	/*Select p ... Calls("q",p)*/
	else if(arg1.argumentType==PROCARGUMENT && arg2.argumentType==ARGUMENT)
	{
		result2 = call->getProcCalled(arg1.argument);

		if(result2.at(0)==-1)
			result2.pop_back();
		return 2;
	}

	else if(arg1.argumentType==ARGUMENT && arg2.argumentType==ARGUMENT)
	{
		/*Select p ... Calls(p,q)*/
		for(int i=0;i<proc->getSize();i++)
		{
			temp = call->getProcCalled(i);

			for(int j=0;j<temp.size();j++)
			{
				if(temp.at(j)!=-1)
				{
					result1.push_back(i);
					result2.push_back(temp.at(j));
				}
			}

			temp.clear();

			
		}

		return 2;
	}

	if(arg1.argumentType==PROCARGUMENT && arg2.argumentType==PROCARGUMENT)
	{
		if(call->isCalled(arg1.argument, arg2.argument))
			return 1;
		else return -1;
	}

	/*if(result.resultType==RESULT_BOOLEAN)
	{
		if(result.resultVector.size()>0)
			result.resultExists = true;
		else
			result.resultExists = false;
	}*/

	return -2;
}

//------------------Main Function to process Calls* query------------------------

int Mock::getCallsT(vector<int>& result1, vector<int>& result2, Argument arg1, Argument arg2)
{
	vector<PROC_INDEX> temp;
	
	/*Select p ... Calls*("q",p)*/
	if(arg1.argumentType==PROCARGUMENT && arg2.argumentType==ARGUMENT)
	{
		result2 = call->getProcList(arg1.argument);
	
		return 2;
	}

	else if(arg1.argumentType==ARGUMENT && arg2.argumentType==PROCARGUMENT)
	{
		for(int i=0;i<proc->getSize();i++)
		{
			temp=call->getProcList(i);

			for(int j=0;j<temp.size();j++)
				if(temp.at(j)==arg2.argument)
				{
					result1.push_back(i);
					break;
				}
				
		}

		return 2;
	}

	else if(arg1.argumentType==ARGUMENT && arg2.argumentType==ARGUMENT)
	{
		/*Select p ... Calls(p,q)*/
		for(int i=0;i<proc->getSize();i++)
		{
			temp=call->getProcList(i);

			for(int j=0;j<temp.size(); j++)
			{
				if(temp.at(j)!=-1)
				{
					result1.push_back(i);
					result2.push_back(temp.at(j));
				}
			}
			
		}
		

		return 2;
	}

	if(arg1.argumentType==PROCARGUMENT && arg2.argumentType==PROCARGUMENT)
	{
		temp=call->getProcList(arg1.argument);

		for(int i=0;i<temp.size();i++)
			if(temp.at(i)==arg2.argument)
				return 1;
		
		return -1;
	}

	/*if(result.resultType==RESULT_BOOLEAN)
	{
		if(result.resultVector.size()>0)
			result.resultExists = true;
		else
			result.resultExists = false;
	}
*/
	return -2;
}

int Mock::getFollowing(vector<int>&result1, vector<int>& result2,int t1, int t2, int type1){
	int blockEnd;
	if(type1==INTARGUMENT){
		blockEnd = stat->getBlockEnd(t1);
		if(blockEnd!=-1){
			if((STATEMENT_TYPE(t2) == stat->getType(blockEnd))||t2==_STMT){
				result1.push_back(t1);
				result2.push_back(blockEnd);
			}
		}
	}
	else{
		for(int i=0;i<stat->getNoofStat()-1;i++){
			if((STATEMENT_TYPE(t1)==stat->getType(i+1))||t1==_STMT){
				blockEnd = stat->getBlockEnd(i+1);
				if(blockEnd!=-1){
					if((STATEMENT_TYPE(t2) == stat->getType(blockEnd))||t2==_STMT){
						result1.push_back(i+1);
						result2.push_back(blockEnd);
					}
				}
			}
		}
	}
	/*if(STATEMENT_TYPE(type) == stmttype[stmtNum-1]|| type == 6)
	if(blockEnd[stmtNum-1]!=-1)	
	following.push_back(blockEnd[stmtNum-1]);

	return following;*/
	return -1;
}

int Mock::getFollowedby(vector<int>&result1, vector<int>& result2,int t1, int t2,int type2){
	int blockEnd;
	PROC_INDEX p;
	if(type2==INTARGUMENT){
		p = proc->getProcIn(t2);
		for(int j=t2-1;j>=proc->getRangeStart(p);j--){
			blockEnd = stat->getBlockEnd(j);
			if(blockEnd==t2){
				if((STATEMENT_TYPE(t1) == stat->getType(j))||t1==_STMT){
					result1.push_back(j);  //push back the statement number
					result2.push_back(t2);
					break;
				}
			}
		}
	}
	else{
		for(int j=stat->getNoofStat()-1;j>=0;j--)
			if((STATEMENT_TYPE(t2) == stat->getType(j+1))||t2==_STMT){
				p = proc->getProcIn(j+1);
				for(int i=j; i>=proc->getRangeStart(p);i--){
					blockEnd = stat->getBlockEnd(i);
					if(blockEnd==j+1){ //if block end equals the statemnt number
						if((STATEMENT_TYPE(t1)==stat->getType(i))||t1==_STMT){
							result1.push_back(i); // push back the statement number
							result2.push_back(j+1);
							break;
						}
					}
				}
			}
	}


	/*	QRYSTATEMENT_TYPE st = _INTEGER;
	vector<STATEMENT_INDEX> followed;

	for(int j=0;j<blockEnd.size();j++){
	if(blockEnd[j] == blockend && blockEnd[j]!=-1)
	if(STATEMENT_TYPE(type) == stmttype[j]|| type == 6)
	followed.push_back(stmtNo[j]);
	}
	return followed;
	*/
	return -1;
}

int Mock::getFollowingT(vector<int>&result1, vector<int>& result2,int t1,int t2, int type1){
	int stmtnum, lastst;
	if(type1==INTARGUMENT){
		stmtnum=stat->getBlockEnd(t1);
		//lastst=stmtNo.size();
		while(stmtnum!=-1){
			if((STATEMENT_TYPE(t2) == stat->getType(stmtnum))  ||  t2==_STMT){
				result1.push_back(t1);
				result2.push_back(stmtnum);
			}
			stmtnum = stat->getBlockEnd(stmtnum);
		}
	}
	else{
		int j;
		vector<int> tempVector;
		bool isThere;
		for(int i=0;i<stat->getNoofStat()-1;i++){
			/*isThere = false;
			for(j=0;j<tempVector.size();j++){
				if(tempVector[j]==i+1){
					isThere = true;
					break;
				}
			}*/
			//if(!isThere){
				if((STATEMENT_TYPE(t1)==stat->getType(i+1))||t1==_STMT){
					stmtnum = stat->getBlockEnd(i+1);
					//lastst = stmtNo.size();
					while(stmtnum!=-1){
						tempVector.push_back(stmtnum);
						if((STATEMENT_TYPE(t2) == stat->getType(stmtnum))||(t2==_STMT)){
							result1.push_back(i+1);
							result2.push_back(stmtnum);
						}
						stmtnum = stat->getBlockEnd(stmtnum);
					}
				}
			//}
		}
	}

	/*QRYSTATEMENT_TYPE st = _INTEGER;
	vector<STATEMENT_INDEX> followingT;
	int lastst = stmtNo[stmtNo.size()-1];
	int stmtNum = t2-1;
	int lastst = stmtNo[stmtNo.size()-1];
	while(stmtNum!=lastst){
	if((STATEMENT_TYPE(type)==stmttype[stmtNum]||type==6)&&blockEnd[stmtNum]!=-1)
	followingT.push_back(blockEnd[stmtNum]);
	stmtNum = blockEnd[stmtNum];
	}
	return followingT;*/
	return -1;
}

int Mock::getFollowedbyT(vector<int>& result1,vector<int>& result2,int t1, int t2, int type2){
	//need to add line to get range start for the given statement t2 and lop only until rangestart
	int stmtnum;	
	PROC_INDEX p = proc->getProcIn(t2);
	if(type2==INTARGUMENT){
		stmtnum = t2;
		for(int j=t2-1;j>=proc->getRangeStart(p);j--){
			if(stat->getBlockEnd(j)==stmtnum){
				stmtnum = j;
				if((STATEMENT_TYPE(t1) == stat->getType(stmtnum))||t1==_STMT){
					result1.push_back(stmtnum);
					result2.push_back(t2);
				}
			}
		}
	}
	else{
		int k;
		bool isThere;
		vector<int> tempVector;
		for(int j=stat->getNoofStat()-1;j>=0;j--){
			/*isThere = false;
			for(k=0;k<tempVector.size();k++){
				if(tempVector[k]==j+1){
					isThere=true;
					break;
				}
			}*/
			//if(!isThere){
				stmtnum = j+1;
				if((STATEMENT_TYPE(t2) == stat->getType(stmtnum))||t2==_STMT){
					p = proc->getProcIn(stmtnum);
					for(int i=j; i>=proc->getRangeStart(p);i--){
						if(stat->getBlockEnd(i)==stmtnum){
							stmtnum = i;
							tempVector.push_back(stmtnum);// push back statement number
							if((STATEMENT_TYPE(t1)==stat->getType(stmtnum))||t1==_STMT){
								result1.push_back(stmtnum);
								result2.push_back(j+1);
							}
						}
					}
				}
			//}
		}
	}

	/*vector<STATEMENT_INDEX> followedT;
	int stmtNum = t2-1;
	for(int j=stmtNum;j>0;j--)
	if(stmtNo[j] == blockEnd[j-1]&&blockEnd[j-1]!=-1)
	followedT.push_back(stmtNo[j]);
	*/
	return -1;
}

int Mock::getNextafter(vector<int>&result1, vector<int>& result2,int t1, int t2, int type1){
	vector<int> next;
	if(type1==INTARGUMENT){
		next = stat->getNext(t1);
		if(next.size()!=0){
			for(int i=0;i<next.size();i++){
				if((STATEMENT_TYPE(t2) == stat->getType(next[i]))||t2==_STMT){
					result1.push_back(t1);
					result2.push_back(next[i]);
				}
			}
		}
	}
	else{
		for(int i=0;i<stat->getNoofStat()-1;i++){
			if((STATEMENT_TYPE(t1)==stat->getType(i+1))||t1==_STMT){
				next = stat->getNext(i+1);
				if(next.size()!=0){
					for(int j=0;j<next.size();j++){
						if((STATEMENT_TYPE(t2) == stat->getType(next[j]))||t2==_STMT){
							result1.push_back(i+1);
							result2.push_back(next[j]);
						}
					}
				}
			}
		}
	}
	/*if(STATEMENT_TYPE(type) == stmttype[stmtNum-1]|| type == 6)
	if(blockEnd[stmtNum-1]!=-1)	
	following.push_back(blockEnd[stmtNum-1]);

	return following;*/
	return -1;
}

int Mock::getNextbefore(vector<int>& result1, vector<int>&result2, int t1, int t2,int type2){
	vector<int> next;
	PROC_INDEX p;
	bool flag;
	int m;
	if(type2==INTARGUMENT){
		p = proc->getProcIn(t2);
		for(int j=t2-1;j>=proc->getRangeStart(p);j--){
			next = stat->getNext(j);
			for(int n=0;n<next.size();n++){
				if(next[n]==t2){
					if((STATEMENT_TYPE(t1) == stat->getType(next[n]))||t1==_STMT){
						for(m=0;m<result1.size();m++)
							if(result1[m]==j)
								break;
						if(m==result1.size()){
						result1.push_back(j);  //push back the statement number
						result2.push_back(t2);
						}
					}
				}
			}
		}
		if(stat->getType(t2) == _WHILE){
			int blockend = stat->getBlockEnd(t2);
			if(blockend!=-1){
				if((STATEMENT_TYPE(t1) == stat->getType(blockend-1))||t1==_STMT){
					for(int m=0;m<result1.size();m++)
						if(result1[m]==blockend-1)
							return -1;
					result1.push_back(blockend-1);
					result2.push_back(t2);
				}	    
			}
			else{
				int k;
				for(k=t2+1;k<=proc->getRangeEnd(p);k++){
					if(stat->getParent(k)<t2)
						break;
				}
				if((STATEMENT_TYPE(t1) == stat->getType(k-1))||t1==_STMT){
					for(int m=0;m<result1.size();m++)
						if(result1[m]==k-1)
							return -1;
					result1.push_back(k-1);
					result2.push_back(t2);
				}
			}
		}
	}
	else{
		for(int j=stat->getNoofStat()-1;j>=0;j--)
			if((STATEMENT_TYPE(t2) == stat->getType(j+1))||t2==_STMT){
				p = proc->getProcIn(j+1);
				for(int i=j; i>=proc->getRangeStart(p);i--){
					next = stat->getNext(i);
					for(int n=0;n<next.size();n++){
						if(next[n]==j+1){ //if next equals the statemnt number
							if((STATEMENT_TYPE(t1)==stat->getType(next[n]))||t1==_STMT){
								result1.push_back(next[n]); // push back the statement number
								result2.push_back(j+1);
							}
						}
					}
				}
				if(stat->getType(j+1) == _WHILE){
					int stmtnum = j+1;
					int blockend = stat->getBlockEnd(stmtnum);
					if(blockend!=-1){
						if((STATEMENT_TYPE(t1) == stat->getType(blockend-1))||t1==_STMT){
							result1.push_back(blockend-1);
							result2.push_back(stmtnum);
						}	    
					}
					else{
						int k;
						p = proc->getProcIn(stmtnum);
						for(k=stmtnum+1;k<=proc->getRangeEnd(p);k++){
							if(stat->getParent(k)<t2)
								break;
						}
						if((STATEMENT_TYPE(t1) == stat->getType(k-1))||t1==_STMT){
							result1.push_back(k-1);
							result2.push_back(t2);
						}
					}
				}
			}
	}
	return -1;
}

int Mock::getNextafterT(vector<int>&result1, vector<int>& result2,int t1,int t2, int type1){
	int stmtnum, lastst;
	if(type1==INTARGUMENT){
		vector<int> next = stat->getNext(t1);
		vector<int> temp;
		bool isfound;
		PROC_INDEX p = proc->getProcIn(t1);
		int end = proc->getRangeEnd(p);
		if(next.size()!=0){
			for(int n=0;n<next.size();n++){
				temp.push_back(next[n]);
			}
			for(int i=0;i<temp.size();i++){
				if((STATEMENT_TYPE(t2) == stat->getType(temp[i]))||(t2==_STMT))
					result2.push_back(temp[i]);
				next = stat->getNext(temp[i]);
				for(int n=0;n<next.size();n++){
					isfound=false;
					for(int k=0;k<temp.size();k++){
						if(temp[k]==next[n]){
							isfound=true;
							break;
						}
					}
					if(!isfound)
					temp.push_back(next[n]);
				}
			}
		}

		/*for(int i=t1;i<end;i++){
			for(int k=0;k<temp.size();k++){
				if(temp[k]==i){
					isfound = true;
					break;
				}
			}
			if(isfound){
				next = stat->getNext(i);
				for(int i=0;i<next.size();i++){
					temp.push_back(next[i]);
					if((STATEMENT_TYPE(t2) == stat->getType(next[i]))||(t2==_STMT)){
						result2.push_back(next[i]);				
					}
				}
			}
			isfound = false;
		}*/
	}	
	else{
		int j;
		vector<int>next;
		vector<int> temp;
		bool isfound;
		for(int i=0;i<stat->getNoofStat()-1;i++){
			if((STATEMENT_TYPE(t1)==stat->getType(i+1))||t1==_STMT){
				PROC_INDEX p = proc->getProcIn(i+1);
				int end = proc->getRangeEnd(p);
				int stmtnum = i+1;
				next = stat->getNext(stmtnum);
				if(next.size()!=0){
					for(int n=0;n<next.size();n++){
						temp.push_back(next[n]);
					}
					for(int j=0;j<temp.size();j++){
						if((STATEMENT_TYPE(t2) == stat->getType(temp[j]))||(t2==_STMT)){
							result1.push_back(stmtnum);
							result2.push_back(temp[j]);
						}
						next = stat->getNext(temp[j]);
						for(int n=0;n<next.size();n++){
							isfound=false;
							for(int k=0;k<temp.size();k++){
								if(temp[k]==next[n]){
									isfound=true;
									break;
								}
							}
							if(!isfound)
								temp.push_back(next[n]);
						}
					}
				}
			}
			temp.clear();
		}
	}
	return -1;
}

int Mock::getNextbeforeT(vector<int>& result1, vector<int>&result2, int t1, int t2,int type2){
	vector<int> next;
	vector<int> temp1;
	PROC_INDEX p;
	bool flag;
	if(type2==INTARGUMENT){
		int x = getNextbefore(temp1,result2,t1,t2,type2);
		for(int i=0;i<temp1.size();i++){
			if((STATEMENT_TYPE(t1) == stat->getType(temp1[i]))||t1==_STMT)
				result1.push_back(temp1[i]);
			getNextbefore(temp1,result2,t1,temp1[i],INTARGUMENT);

		}
	}
	return -1;
}

int Mock::getPar(vector<int>& result1,vector<int>& result2,int t1, int t2, int type2){
	int parent;
	if(type2==INTARGUMENT){
		parent = stat->getParent(t2);
		if(parent!=-1){
			if((STATEMENT_TYPE(t1) == stat->getType(parent))||t1==_STMT){
				result1.push_back(parent);
				result2.push_back(t2);
			}
		}
	}
	else{
		for(int i=stat->getNoofStat()-1;i>=0;i--){
			if((STATEMENT_TYPE(t2)==stat->getType(i+1))||t2==_STMT){
				parent = stat->getParent(i+1);
				if(parent!=-1)
					if((STATEMENT_TYPE(t1) == stat->getType(parent))||t1==_STMT){
					result1.push_back(parent);
					result2.push_back(i+1);
					}
			}
		}
	}
	return -1;
}

int Mock::getChild(vector<int>& result1,vector<int>& result2,int t1, int t2,int type1){
	int parent;
	PROC_INDEX p;
	if(type1==INTARGUMENT){
		p = proc->getProcIn(t1);
		for(int j=t1+1;j<=proc->getRangeEnd(p);j++){
			if(stat->getParent(j)<t1)
				break;
			else if(stat->getParent(j)==t1){
				if((STATEMENT_TYPE(t2) == stat->getType(j))||t2==_STMT){
					result1.push_back(t1);
					result2.push_back(j);//push back statement
				}
			}
		}
	}
	else{
		for(int j=0;j<stat->getNoofStat();j++)
			if((STATEMENT_TYPE(t1) == stat->getType(j+1))||t1==_STMT){
				p = proc->getProcIn(j+1);
				for(int i=j+1; i<proc->getRangeEnd(p);i++){
					if(stat->getParent(i+1)<j+1)
						break;
					if(stat->getParent(i+1)==j+1){
						if((STATEMENT_TYPE(t2)==stat->getType(i+1))||t2==_STMT){
							result1.push_back(j+1);
							result2.push_back(i+1);//push back statement number
						}
					}
				}
			}
	}
	return -1;
}

int Mock::getParT(vector<int>& result1,vector<int>& result2,int t1,int t2, int type2){
	int stmtnum, parent;
	if(type2==INTARGUMENT){
		stmtnum=t2;
		while(stmtnum>1){
			parent = stat->getParent(stmtnum);
			if(parent != -1){
				if((STATEMENT_TYPE(t1) == stat->getType(parent))  ||  t1==_STMT){
					result1.push_back(parent);
					result2.push_back(t2);
				}
			}
			stmtnum = parent;
		}
	}
	else{
		int j;
		bool isThere;
		for(int i=stat->getNoofStat()-1;i>0;i--){
			/*isThere = false;
			for(j=0;j<result.size();j++){
				if(result[j]==i+1){
					isThere = true;
					break;
				}
			}*/
			//if(!isThere){
				stmtnum = i+1;
				if((STATEMENT_TYPE(t2)==stat->getType(stmtnum))||t2==_STMT){
					while(stmtnum>1){
						parent = stat->getParent(stmtnum);
						if(parent!=-1){
							if((STATEMENT_TYPE(t1) == stat->getType(parent))||(t1==_STMT)){
								result1.push_back(parent);
								result2.push_back(i+1);
							}
						}
						stmtnum = parent;
					}
				}
			//}
		}
	}
		return -1;
}

int Mock::getChildT(vector<int>& result1,vector<int>& result2,int t1, int t2, int type1){
	int parent;
	PROC_INDEX p;
	if(type1==INTARGUMENT){
		p = proc->getProcIn(t1);
		for(int j=t1+1;j<=proc->getRangeEnd(p);j++){
			if(stat->getParent(j)<t1)
				break;
			//else if(stat->getParent(j)==t1){
				if((STATEMENT_TYPE(t2) == stat->getType(j))||t2==_STMT){
					result1.push_back(t1);
					result2.push_back(j);//push back statement
				}
			//}
		}
	}
	else{
		for(int j=0;j<stat->getNoofStat();j++)
			if((STATEMENT_TYPE(t1) == stat->getType(j+1))||t1==_STMT){
				p = proc->getProcIn(j+1);
				for(int i=j+1; i<proc->getRangeEnd(p);i++){
					if(stat->getParent(i+1)<j+1)
						break;
					if(stat->getParent(i+1)==j+1){
						if((STATEMENT_TYPE(t2)==stat->getType(i+1))||t2==_STMT){
							result1.push_back(j+1);
							result2.push_back(i+1);//push back statement number
						}
					}
				}
			}
	}
	return -1;
}

int Mock::getModifies(vector<int>& result1, vector<int>& result2, Argument arg1, Argument arg2)
{
	STMT_LIST temp;

	int selectedType=arg1.argument;
	
	if(arg1.argumentType==ARGUMENT && arg2.argumentType==VARARGUMENT)
	{
		/* Example: (p,"i") */ //Modifies
		if(arg1.argument==_PROCEDURE)
			result1=modvar->getProcModifiedIn(arg2.argument);

		/* Example: (a,"i") */ //Modifies
		else if(arg1.argument==_ASSIGN)
		{
			temp=modvar->getStmtModifiedIn(arg2.argument);
			
			for(int i=0;i<temp.size();i++)
			{
				if(stat->getType(temp.at(i))==STATEMENT_Assign)
					result1.push_back(temp.at(i));
			}
		}

		/* Example: (s,"i") */ //Modifies
		else if(arg1.argument==_STMT)
			result1=modvar->getStmtModifiedIn(arg2.argument);

		/* Example: (w,"i") */ //Modifies
		else if(arg1.argument==_WHILE)
		{
			temp=modvar->getStmtModifiedIn(arg2.argument);
			
			for(int i=0;i<temp.size();i++)
			{
				if(stat->getType(temp.at(i))==STATEMENT_While)
					result1.push_back(temp.at(i));
			}
		}

		/* Example: (if,"i") */ //Modifies
		else if(arg1.argument==_IF)
		{
			temp=modvar->getStmtModifiedIn(arg2.argument);
			
			for(int i=0;i<temp.size();i++)
			{
				if(stat->getType(temp.at(i))==STATEMENT_If)
					result1.push_back(temp.at(i));
			}
		}

		else if(arg1.argument==_CALL)
		{
			temp=modvar->getStmtModifiedIn(arg2.argument);
			
			for(int i=0;i<temp.size();i++)
			{
				if(stat->getType(temp.at(i))==STATEMENT_Call)
					result1.push_back(temp.at(i));
			}
		}


		return 2;
	
	}

	else if(arg1.argumentType==ARGUMENT && arg2.argumentType==ARGUMENT)
	{
		/* Example: Select a ... (a,v) */ //Modifies
		if(selectedType==_ASSIGN)
		{
			for(int i=1;i<=stat->getNoofStat();i++)
				if(stat->getType(i)==STATEMENT_Assign)
				{
					temp=modstat->getVarModified(i);
					
					for(int j=0;j<temp.size();j++)
					{
						if(temp.at(j)!=-1)
						{
							result1.push_back(i);
							result2.push_back(temp.at(j));
						}
					}

					temp.clear();

				}
		}

		/* Example: Select s ... (s,v) */ //Modifies
		else if(selectedType==_STMT)
		{
			for(int i=1;i<=stat->getNoofStat();i++)
			{
				temp=modstat->getVarModified(i);
					
				for(int j=0;j<temp.size();j++)
				{
					if(temp.at(j)!=-1)
					{
						result1.push_back(i);
						result2.push_back(temp.at(j));
					}
				}
				
				temp.clear();

			}
		}

		/* Example: Select w ... (w,v) */ //Modifies
		else if(selectedType==_WHILE)
		{
			for(int i=1;i<=stat->getNoofStat();i++)
				if(stat->getType(i)==STATEMENT_While)
				{
					temp=modstat->getVarModified(i);
					
					for(int j=0;j<temp.size();j++)
					{
						if(temp.at(j)!=-1)
						{
							result1.push_back(i);
							result2.push_back(temp.at(j));
						}
					}

					temp.clear();

				}
		}

		/* Select c ... Modifies(c,v)*/
		else if(selectedType==_CALL)
		{
			for(int i=1;i<=stat->getNoofStat();i++)
				if(stat->getType(i)==STATEMENT_Call)
				{
					temp=modstat->getVarModified(i);
					
					for(int j=0;j<temp.size();j++)
					{
						if(temp.at(j)!=-1)
						{
							result1.push_back(i);
							result2.push_back(temp.at(j));
						}
					}

					temp.clear();

				}
		}


		/* Example: Select if ... (if,v) */ //Modifies
		else if(selectedType==_IF)
		{
			for(int i=1;i<=stat->getNoofStat();i++)
				if(stat->getType(i)==STATEMENT_If)
				{
					temp=modstat->getVarModified(i);
					
					for(int j=0;j<temp.size();j++)
					{
						if(temp.at(j)!=-1)
						{
							result1.push_back(i);
							result2.push_back(temp.at(j));
						}
					}

					temp.clear();

				}

				return 2;
		}

		/* Example: Select p ... (p,v) */ //Modifies
		else if(selectedType==_PROCEDURE)
		{
			for(int i=0;i<proc->getSize();i++)
			{
				temp=modproc->getVarModified(i);
				
				for(int j=0;j<temp.size();j++)
				{
					if(temp.at(j)!=-1)
					{
						result1.push_back(i);
						result2.push_back(temp.at(j));
					}
				}

				temp.clear();

			}
		}

		return 2;
		
	}

	else if(arg1.argumentType==INTARGUMENT && arg2.argumentType==VARARGUMENT)
	{
		if(modstat->isModified(arg1.argument, arg2.argument))
			return 1;
		else return -1;

	}

	else if(arg1.argumentType==PROCARGUMENT && arg2.argumentType==VARARGUMENT)
	{
		if(modproc->isModified(arg1.argument, arg2.argument))
			return 1;
		else return -1;

	}

	return -2;

}

int Mock::getModifiedBy(vector<int>& result1, vector<int>& result2, Argument arg1, Argument arg2)
{
	int selectedType=arg2.argument;
	STMT_LIST temp;
	
	/* Example: (5,v) */ //Modified By
	if(arg1.argumentType==INTARGUMENT && arg2.argumentType==ARGUMENT)
	{
		result2=modstat->getVarModified(arg1.argument);

		return 2;
	}

	/* Example: ("p",v) */ //Modified By
	else if(arg1.argumentType==PROCARGUMENT && arg2.argumentType==ARGUMENT)
	{
		if(arg2.argument==_VARIABLE)
		{
			result2=modproc->getVarModified(arg1.argument);
		}

		return 2;
	}

	return -2;
	
}

int Mock::getUsess(vector<int>& result1, vector<int>& result2, Argument arg1, Argument arg2)
{
	int selectedType=arg1.argument;
	STMT_LIST temp;

	if((arg1.argumentType==ARGUMENT) && (arg2.argumentType==VARARGUMENT))
	{
		/* Example: (p,"v") */ //Uses
		if(arg1.argument==_PROCEDURE)
			result1=usevar->getProcUsedIn(arg2.argument);

		/* Example: (a,"v") */ //Uses
		else if(arg1.argument==_ASSIGN)
		{
			temp=usevar->getStmtUsedIn(arg2.argument);
			
			for(int i=0;i<temp.size();i++)
			{
				if(stat->getType(temp.at(i))==STATEMENT_Assign)
					result1.push_back(temp.at(i));
			}
		}

		/* Example: (s,"v") */ //Uses
		else if(arg1.argument==_STMT)
			result1=usevar->getStmtUsedIn(arg2.argument);

		/* Example: (w,"v") */ //Uses
		else if(arg1.argument==_WHILE)
		{
			temp=usevar->getStmtUsedIn(arg2.argument);
			
			for(int i=0;i<temp.size();i++)
			{
				if(stat->getType(temp.at(i))==STATEMENT_While)
					result1.push_back(temp.at(i));
			}
		}

		/* Example: (if,"v") */ //Uses
		else if(arg1.argument==_IF)
		{
			temp=usevar->getStmtUsedIn(arg2.argument);
			
			for(int i=0;i<temp.size();i++)
			{
				if(stat->getType(temp.at(i))==STATEMENT_If)
					result1.push_back(temp.at(i));
			}
		}
		
		/* Select c ... Uses(c,"v")*/
		else if(arg1.argument==_CALL)
		{
			temp=usevar->getStmtUsedIn(arg2.argument);
			
			for(int i=0;i<temp.size();i++)
			{
				if(stat->getType(temp.at(i))==STATEMENT_Call)
					result1.push_back(temp.at(i));
			}
		}
		return 2;
	}

	else if((arg1.argumentType==ARGUMENT) && (arg2.argumentType==ARGUMENT))
	{
		/* Example: Select a ... (a,v) */ //Uses
		if(selectedType==_ASSIGN)
		{
			for(int i=1;i<=stat->getNoofStat();i++)
				if(stat->getType(i)==STATEMENT_Assign)
				{
					temp=usestat->getVarUsed(i);
					
					for(int j=0;j<temp.size();j++)
					{
						if(temp.at(j)!=-1)
						{
							result1.push_back(i);
							result2.push_back(temp.at(j));
						}
					}

					temp.clear();
				}
		}

		/* Example: Select s ... (s,v) */ //Uses
		else if(selectedType==_STMT)
		{
			for(int i=1;i<=stat->getNoofStat();i++)
			{
				temp=usestat->getVarUsed(i);
					
				for(int j=0;j<temp.size();j++)
				{
					if(temp.at(j)!=-1)
					{
						result1.push_back(i);
						result2.push_back(temp.at(j));
					}
				}

				temp.clear();
			}
		}

		else if(selectedType==_CALL)
		{
			for(int i=1;i<=stat->getNoofStat();i++)
				if(stat->getType(i)==STATEMENT_Call)
				{
					temp=usestat->getVarUsed(i);
					
					for(int j=0;j<temp.size();j++)
					{
						if(temp.at(j)!=-1)
						{
							result1.push_back(i);
							result2.push_back(temp.at(j));
						}
					}

					temp.clear();
				}
		}

		/* Example: Select w ... (w,v) */ //Uses
		else if(selectedType==_WHILE)
		{
			for(int i=1;i<=stat->getNoofStat();i++)
				if(stat->getType(i)==STATEMENT_While)
				{
					temp=usestat->getVarUsed(i);
					
					for(int j=0;j<temp.size();j++)
					{
						if(temp.at(j)!=-1)
						{
							result1.push_back(i);
							result2.push_back(temp.at(j));
						}
					}

					temp.clear();
				}
		}

		/* Example: Select if ... (if,v) */ //Uses
		else if(selectedType==_IF)
		{
			for(int i=1;i<=stat->getNoofStat();i++)
				if(stat->getType(i)==STATEMENT_If)
				{
					temp=usestat->getVarUsed(i);
					
					for(int j=0;j<temp.size();j++)
					{
						if(temp.at(j)!=-1)
						{
							result1.push_back(i);
							result2.push_back(temp.at(j));
						}
					}

					temp.clear();
				}
		}

		/* Example: Select p ... (p,v) */ //Uses
		else if(selectedType==_PROCEDURE)
		{
			for(int i=0;i<proc->getSize();i++)
				if(useproc->getVarUsed(i).at(0)!=-1)
				{
					temp=usestat->getVarUsed(i);
					
					for(int j=0;j<temp.size();j++)
					{
						if(temp.at(j)!=-1)
						{
							result1.push_back(i);
							result2.push_back(temp.at(j));
						}
					}

					temp.clear();
				}

			
		}

		return 2;

	}

	else if(arg1.argumentType==INTARGUMENT && arg2.argumentType==VARARGUMENT)
	{
		if(usestat->isUsed(arg1.argument, arg2.argument))
			return 1;
		else return -1;

	}

	else if(arg1.argumentType==PROCARGUMENT && arg2.argumentType==VARARGUMENT)
	{
		if(useproc->isUsed(arg1.argument, arg2.argument))
			return 1;
		else return -1;

	}

	return -2;
}
int Mock::getUsedBy(vector<int>& result1, vector<int>& result2, Argument arg1, Argument arg2)
{
	int selectedType=arg2.argument;
	STMT_LIST temp;

	/* Example: (5,v) */ //Used By
	if(arg1.argumentType==INTARGUMENT && arg2.argumentType==ARGUMENT)
	{
		result2=usestat->getVarUsed(arg1.argument);

		return 2;
	}

	else if((arg1.argumentType==PROCARGUMENT) && (arg2.argumentType==ARGUMENT))
	{
		/* Example: ("p",v) */ //Used By
		if(arg2.argument==_VARIABLE)
		{
			result2=useproc->getVarUsed(arg1.argument);
		}

		return 2;
	}

	return -2;
}


//------------------Function to validate a statement or constant in a query------------------------
int Mock::validateEntity(int num, int type){
	if(type==_CONSTANT){
		int constant;
		for(int i=0;i<var->getTotalSize();i++)
			if(var->getVarType(i) == NUMERIC_EXPR_TYPE_CONSTANT){
				string s = var->getVarName(i);
				constant = atoi(&s[0]);
				if(constant == num)
					return 1;
			}
	}
	else if(num<=stat->getNoofStat())
		return 1;

	return -1;
}

//---------------Function to get index of variable or procedure------------------
int Mock::getEntityIndex(string e,int type){
	if(type==8) //if type is variable
		return var->getVarIndex(e);
	return proc->getProcIndex(e);//if type is procedure

}
//---------------Function to get type of entity and its index------------------
int Mock::getEntityTypeIndex(string e,int &type){
	int x;
	x = var->getVarIndex(e);
	if(x!=-1){
		type = 8; // need to decide what to return if its variable
		return x;
	}
	x = proc->getProcIndex(e);
	type = 9;
	return x;
}

string Mock::getEntityName(int index, int type){
	if(type==_VARIABLE)
		return var->getVarName(index);
	else if(type==_PROCEDURE)
		return proc->getProcName(index);
	return "ERROR";
}

int Mock::getWith(vector<int>& result1, vector<int>& result2, Argument arg1, Argument arg2){
       if(arg1.argument==_PROCEDURE||arg1.argument==_VARIABLE){
               if(arg1.argument==arg2.argument){
                       if(arg2.argument==_PROCEDURE){
                               for(int i=0;i<proc->getSize();i++){
                                       result2.push_back(i);
									   result1.push_back(i);
							   }
                       }
                       else if(arg2.argument==_VARIABLE){
                               for(int i=0;i<var->getTotalSize();i++){
								   if(var->getVarType(i) == NUMERIC_EXPR_TYPE_VARIABLE){
                                       result2.push_back(i);
									   result1.push_back(i);
								   }
							   }
                       }
               }
			   else if(arg1.argumentType==_PROCEDURE){
                       for(int i=0;i<proc->getSize();i++){
                               for(int j=0;j<var->getTotalSize();j++){
								   if(var->getVarType(j) == NUMERIC_EXPR_TYPE_VARIABLE)
                                       if((var->getVarName(j).compare(proc->getProcName(i))==0)){
                                               result1.push_back(i);
											   result2.push_back(j);
                                               break;
                                       }
							   }
                       }
               }
			   else{
                       for(int i=0;i<var->getTotalSize();i++){
						   if(var->getVarType(i) == NUMERIC_EXPR_TYPE_VARIABLE){
                               for(int j=0;j<proc->getSize();j++)
                                       if((var->getVarName(i).compare(proc->getProcName(j))==0)){
                                               result1.push_back(i);
											   result2.push_back(j);
											   break;
                                       }
						   }
                       }
               }
       }
       else if(arg1.argument==_STMT && arg2.argument==_CONSTANT){
               int constant;
               for(int i=0;i<var->getTotalSize();i++){
				   if(var->getVarType(i) == NUMERIC_EXPR_TYPE_CONSTANT){
                       string s = var->getVarName(i);
                       constant = atoi(&s[0]);
                       for(int j=0;j<stat->getNoofStat();j++)
                               if(j==constant){
                                       result1.push_back(constant);
									   result2.push_back(constant);
                                       break;
                               }
				   }
               }

	   }
	   if(result1.size()==0||result2.size()==0)
		   return 1;
	   return -1;
}


